package com.daafan.minilib.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;

public class ImageUtils {

	public static final String	CAMERA_DIR	= AppUtils.getMyCacheDir("/my_camera/");

	/**
	 * 放大缩小图片
	 * 
	 * @param bitmap
	 * @param w
	 * @param h
	 * @return
	 */
	public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
		Matrix matrix = new Matrix();

		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		float scaleWidht = ((float) w / width);
		float scaleHeight = ((float) h / height);

		matrix.postScale(scaleWidht, scaleHeight);// 获取缩放比例
													// 根据缩放比例获取新的位图
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
		return newbmp;
	}

	/**
	 * 手动缩放图片
	 * 
	 * @param uri
	 * @param requestCode
	 */
	public static void zoomPhoto(Uri uri, int requestCode) {
		zoomPhoto(uri, requestCode, 0, 0, 0, 0);
	}

	/**
	 * 手动缩放图片
	 * 
	 * @param uri
	 * @param requestCode
	 * @param aspectX
	 *            裁剪框比例
	 * @param aspectY
	 * @param outputX
	 *            /输出图片大小
	 * @param outputY
	 */
	public static void zoomPhoto(Uri uri, int requestCode, int aspectX, int aspectY, int outputX, int outputY) {
		if (!uri.toString().startsWith("file://")) {
			uri = Uri.parse("file://" + uri.toString());
		}

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(uri, "image/*");
		intent.putExtra("crop", "true");
		intent.putExtra("noFaceDetection", true);

		if (aspectX != 0 || aspectY != 0) {
			intent.putExtra("aspectX", aspectX);
			intent.putExtra("aspectY", aspectY);
		}

		if (outputX != 0) {
			intent.putExtra("outputX", outputX);
		}
		if (outputY != 0) {
			intent.putExtra("outputY", outputY);
		}

		// photoFile只是output用
		if (photoFile == null || (photoFile != null && photoFile.getPath().equals(""))) {
			photoFile = new File(CAMERA_DIR + System.currentTimeMillis() / 1000 + ".jpg");// photoFile跟拍照的uri不一样，因为currentTime不一样

			if (!photoFile.getParentFile().exists()) {
				photoFile.getParentFile().mkdirs();
			}
		}

		String url = photoFile.getPath().substring(0, photoFile.getPath().length() - 4) + "_cut.jpg";
		photoFile = new File(url);

		intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));// 只能传入uri
		if (mContextWrapper != null) {
			mContextWrapper.mRequestCode = requestCode;
			mContextWrapper.startActivityForResult(intent, requestCode);
		}
		zoom = true;
	}

	/**
	 * 将Drawable转化为Bitmap
	 * 
	 * @param drawable
	 * @return
	 */
	public static Bitmap drawableToBitmap(Drawable drawable) {
		int width = drawable.getIntrinsicWidth();
		int height = drawable.getIntrinsicHeight();
		Bitmap bitmap = Bitmap.createBitmap(width, height, drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
				: Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, width, height);
		drawable.draw(canvas);
		return bitmap;

	}

	/**
	 * 获得圆角图片的方法
	 * 
	 * @param bitmap
	 * @param roundPx
	 * @return
	 */
	public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	/**
	 * 获得带倒影的图片方法
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
		final int reflectionGap = 4;
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		Matrix matrix = new Matrix();
		matrix.preScale(1, -1);

		Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2, width, height / 2, matrix, false);

		Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888);

		Canvas canvas = new Canvas(bitmapWithReflection);
		canvas.drawBitmap(bitmap, 0, 0, null);
		Paint deafalutPaint = new Paint();
		canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);

		canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
				0x00ffffff, TileMode.CLAMP);
		paint.setShader(shader);
		// Set the Transfer mode to be porter duff and destination in
		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
		// Draw a rectangle using the paint with our linear gradient
		canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);

		return bitmapWithReflection;
	}

	public static byte[] getImage(String urlStr) throws Exception {
		URL url = new URL(urlStr);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(5 * 1000);
		InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据
		try {
			return readInputStream(inStream);// 得到图片的二进制数据
		} catch (OutOfMemoryError e) {
			System.gc();
			return null;
		}
	}

	/**
	 * 从输入流中获取数据
	 * 
	 * @param inStream
	 *            输入流
	 * @return
	 * @throws Exception
	 */
	public static byte[] readInputStream(InputStream inStream) throws Exception {
		byte[] buffer = new byte[1024];
		int len = 0;
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		inStream.close();
		return outStream.toByteArray();
	}

	public static String UriToString(Uri uri) {
		if (uri == null)
			return null;

		String url = null;
		if (uri.toString().startsWith("file:")) {

			url = uri.toString().substring(7);

		} else {
			if (mContextWrapper != null && mContextWrapper.mActivity != null) {
				String[] proj = { MediaStore.Images.Media.DATA };

				@SuppressWarnings("deprecation")
				Cursor actualimagecursor = mContextWrapper.mActivity.managedQuery(uri, proj, null, null, null);

				int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

				actualimagecursor.moveToFirst();

				String img_path = actualimagecursor.getString(actual_image_column_index);

				return img_path;
			}
		}
		return url;
	}

	// private static Map<String, Uri> photoMap = new HashMap<String, Uri>();
	/** 拍照存放的临时图片 */
	private static File				photoFile;
	private static ContextWrapper	mContextWrapper;
	private static boolean			camera;
	private static boolean			zoom;

	private static void initImage() {
		photoFile = null;
		camera = false;
		zoom = false;
	}

	/**
	 * 通过Intent获取图片(摄像头、本地等)
	 * 
	 * @param activity
	 * 
	 *            如果fragment!=null,则activity只作为Context用， {@link Fragment#onActivityResult()}
	 *            回调；如果fragment==null，则需要activity.startActivityForResult(...)。 Activity的 {@link Activity#onActivityResult()}会回调
	 * @param fragment
	 *            这个fragment的onActivityResult()会回调
	 * @param requestCode
	 * @param original
	 *            是否获取原图
	 */
	private static void takePhoto(final Activity activity, final Fragment fragment, String title, final int requestCode, final boolean original) {
		initImage();

		mContextWrapper = new ContextWrapper(activity, fragment, requestCode);

		AlertDialog.Builder builder = new AlertDialog.Builder(activity);
		builder.setTitle(title);
		builder.setItems(new String[] { "拍照", "从相册选择" }, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				switch (which) {
				case 0:// 拍照

					photoFile = new File(CAMERA_DIR + System.currentTimeMillis() / 1000 + ".jpg");
					if (original) {
						// 获取原图
						if (!photoFile.getParentFile().exists()) {
							photoFile.getParentFile().mkdirs();
						}

						Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
						intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));

						mContextWrapper.startActivityForResult(intent, requestCode);
					} else {
						// 非原图
						Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
						mContextWrapper.startActivityForResult(intent, requestCode);
					}

					camera = true;
					break;

				case 1:
					Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
					mContextWrapper.startActivityForResult(intent, requestCode);

					break;
				default:
					break;
				}
			}
		});

		AlertDialog alert = builder.create();
		alert.setCancelable(true);
		alert.setCanceledOnTouchOutside(true);
		alert.show();
	}

	/**
	 * 从手机选择图片 or 拍照。在{@linkplain Activity#onActivityResult}(...)回调时，调用 {@link ImageUtils#getPhoto(Activity)}获取图片本地储存路径
	 * 
	 * @param activity
	 * @param requestCode
	 */
	public static void takePhoto(Activity activity, String title, int requestCode) {
		takePhoto(activity, null, title, requestCode, true);
	}

	/**
	 * 从手机选择图片 or 拍照。在{@linkplain Fragment#onActivityResult}(...)回调时，调用 {@link ImageUtils#getPhoto(Activity)}获取图片本地储存路径
	 * 
	 * @param fragment
	 * @param requestCode
	 */
	public static void takePhoto(Fragment fragment, String title, int requestCode) {
		takePhoto(fragment.getActivity(), fragment, title, requestCode, true);
	}

	/**
	 * 调用{@link #takePhoto(Fragment, int)} 或{@link #takePhoto(Activity, int)}后，在 {@linkplain Activity#onActivityResult}(...)回调时，调用此方法，可以获取选择or拍照的图片
	 * 
	 * @return 图片绝对路径
	 */
	public static String getPhotoPath(int requestCode, Intent data) {
		if (mContextWrapper != null && requestCode == mContextWrapper.mRequestCode) {

			String path = "";
			if (camera == true || zoom == true) {
				path = photoFile + "";
			} else if (data != null && data.getData() != null) {
				path = UriToString(data.getData());// 选择相册的照片url
			}

			return path;
		}

		return null;
	}

	/**
	 * @return 返回图片Uri
	 */
	public static Uri getPhotoUri(int requestCode, Intent data) {
		String url = getPhotoPath(requestCode, data);
		Uri uri = Uri.parse("file://" + url);

		return uri;
	}

	/** 获取拍照缓存 目录 */
	public static String getCameraDir() {
		return CAMERA_DIR;
	}

	/**
	 * 用来封装Activity或Fragment
	 * 
	 */
	@SuppressWarnings("unused")
	private static class ContextWrapper {

		private int			mRequestCode;
		private Activity	mActivity;
		private Fragment	mFragment;

		public ContextWrapper(Activity activity, Fragment fragment, int requestCode) {
			mRequestCode = requestCode;
			mActivity = activity;
			mFragment = fragment;
		}

		private void startActivityForResult(Intent intent, int requestCode) {
			// Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			if (mFragment != null) {
				mFragment.startActivityForResult(intent, requestCode);// 如果用Activity.RESULT_OK，onActivityResult()不会被回调
			} else if (mActivity != null) {
				mActivity.startActivityForResult(intent, requestCode);
			}
		}
	}
}
